home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / pc / GDM003.ZIP / SOURCE / VOC-IT / INT08.ASM next >
Encoding:
Assembly Source File  |  1994-02-16  |  2.8 KB  |  141 lines

  1. ; INT08.ASM - interrupt and sound handlers for VOC-IT.C
  2.  
  3. ; Written by Phil Inch for Game Developers Magazine (issue 3).
  4. ; Contributed to the public domain.  If you use this program
  5. ; or a derivation thereof in your own programs, please put in
  6. ;    a credit for me and/or the magazine.
  7.  
  8.  
  9. .MODEL large
  10.  
  11. timer_data    EQU 40h
  12. timer_counter    EQU 42h
  13. timer_control    EQU 43h
  14. speaker_port    EQU 61h
  15.  
  16. .CODE
  17.  
  18. PUBLIC _NewInt8Function
  19. PUBLIC _PlaySound
  20.  
  21. ; This new interrupt 8 handler just signals an end-of-interrupt
  22.  
  23. _NewInt8Function PROC far
  24.     push    ax
  25.         mov        al,20h
  26.         out        20h,al
  27.     pop        ax
  28.     iret
  29. _NewInt8Function ENDP
  30.  
  31.  
  32. ; The "PlaySound" routine does the actual work of playing the sound
  33.  
  34. _PlaySound PROC far
  35. ARG data:DWORD, countdown:WORD, os:WORD
  36.  
  37. ; Standard C stack frame prelude
  38.         push    bp
  39.     mov        bp,sp
  40.  
  41. ; Save registers we'll be using
  42.         push    ax
  43.         push    cx
  44.         push    dx
  45.         push    ds
  46.         push    si
  47.  
  48. ; Set up timer 2 to only expect 1 byte countdown values, and to only
  49. ; generate one pulse
  50.         mov        al,10010000b
  51.         out        timer_control,al
  52.  
  53. ; Connect timer 2 to the speaker
  54.         in        al,speaker_port
  55.         or        al,03h
  56.         out        speaker_port,al
  57.  
  58. ; Set timer 0 up with the specified playback frequency
  59.         mov        al,36h
  60.         out        timer_control,al
  61.         mov        cx,[countdown]
  62.         mov        al,cl
  63.         out        timer_data,al
  64.         mov        al,ch
  65.         out        timer_data,al
  66.  
  67. ; Get the address of the sound sample
  68.         lds        si,[data]
  69.     cld
  70.     mov        cx,[os]
  71.  
  72. ; This is where the real work begins.  First we'll "normalise" DS:SI so that
  73. ; SI < 16.
  74. normalise_si:
  75.         cmp        si,16
  76.         jl        play_loop
  77.         sub        si,16
  78.         inc        cx
  79.         jmp        normalise_si
  80.  
  81. ; This is the main loop
  82. play_loop:
  83.         hlt
  84.  
  85. ; if we're oversampling, go straight to the routine that "plays" the byte
  86.     loop    oversample
  87.  
  88. ; otherwise, retrieve the next byte of sample data
  89.     mov        cx,[os]
  90.         lodsb
  91.  
  92. ; if its FFh, that's the end of the sound so exit
  93.         cmp        al,0FFh
  94.         je        sound_finished
  95.  
  96. oversample:
  97. ; send the byte to the timer
  98.         out        timer_counter,al
  99.  
  100. ; update the pointer to the current sample byte.  This method allows us
  101. ; to replay samples longer than 64k by modifing SI directly.  (Every 16
  102. ; increments of SI is equal to one increment of DS).
  103.         cmp        si,16
  104.         jl        play_loop
  105.         xor        si,si
  106.         mov        bx,ds
  107.         inc        bx
  108.         mov        ds,bx
  109.         jmp        play_loop
  110.  
  111. sound_finished:
  112. ; Set the timer back to its original settings (18.2Hz)
  113.         mov        al,00110110b
  114.         out        timer_control,al
  115.         xor        al,al
  116.         out        timer_data,al
  117.         xor        al,al
  118.         out        timer_data,al
  119.  
  120. ; Set timer 2 back to its original settings
  121.         mov        al,10110110b
  122.         out        timer_control,al
  123.  
  124. ; Disconnect timer 2 from the speaker
  125.         in        al,speaker_port
  126.         and        al,0FCh
  127.         out        speaker_port,al
  128.  
  129. ; Restore registers and exit
  130.         pop        si
  131.         pop        ds
  132.         pop        dx
  133.         pop        cx
  134.         pop        ax
  135.     pop        bp
  136.  
  137.     retf
  138. _PlaySound ENDP
  139.  
  140. END
  141.